package com.ruoyi.mqtt;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cs.deviceManager.device.DeviceEventListener;
import com.cs.deviceManager.device.DeviceTypeManager;
import com.cs.deviceManager.domain.DevTelemetryData;
import com.cs.deviceManager.mqtt.DeviceStatus;
import com.cs.deviceManager.mqtt.MqttUtil;
import com.cs.deviceManager.service.IDevDeviceService;
import com.cs.deviceManager.service.IDevTelemetryDataService;
import com.ruoyi.webSocket.DeviceWebSocket;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service("defaultListener")
public class DeviceEventService implements DeviceEventListener {

    @Resource
    private IDevDeviceService devDeviceService;

    @Resource
    private IDevTelemetryDataService devTelemetryDataService;

    private void status(String deviceId) {
        // 获取设备当前状态
        DeviceStatus currentStatus = MqttUtil.getDeviceStatus(deviceId);
        DeviceStatus targetStatus = DeviceStatus.ONLINE;

        // 只有当状态发生变化时才更新数据库和通知WebSocket
        if (currentStatus == null || currentStatus != targetStatus) {
            MqttUtil.setDeviceStatus(deviceId, targetStatus);
            // 1. 更新数据库中的设备状态
            devDeviceService.updateStatus(deviceId, true);
            // 2. 通知 WebSocket 客户端
            DeviceWebSocket.broadcastDeviceStatus(deviceId, true);
        }
    }

    @Override
    public void onDeviceConnected(String deviceId) {
        MqttUtil.setDeviceStatus(deviceId, DeviceStatus.ONLINE);
        devDeviceService.updateStatus(deviceId, true);
        DeviceWebSocket.broadcastDeviceStatus(deviceId, true);
    }

    @Override
    public void onDeviceRecovered(String deviceId, String data) {
        handleDeviceStatusMessage(deviceId, data);
    }

    @Override
    public void onDeviceTelemetry(String deviceId, String data) {
        // 解析数据，确定设备类型
        String deviceType = determineDeviceType(data);

        // 更新设备心跳
        MqttUtil.reportHeartbeat(deviceId, deviceType);

        // 创建遥测数据对象
        DevTelemetryData telemetryData = new DevTelemetryData();
        telemetryData.setDeviceId(deviceId);
        telemetryData.setData(data);
        telemetryData.setReceiveTime(new Date());

        // 保存到数据库
        devTelemetryDataService.insertDevTelemetryData(telemetryData);

        // 通知前端收到新的遥测数据
        notifyDeviceTelemetry(deviceId, data);

        // 处理设备状态消息
        handleDeviceStatusMessage(deviceId, data);
    }

    @Override
    public void onDeviceDisconnected(String deviceId) {
        devDeviceService.updateStatus(deviceId, false);
        DeviceWebSocket.broadcastDeviceStatus(deviceId, false);
    }

    /**
     * 处理设备状态消息
     *
     * @param deviceId 设备ID
     * @param data     消息数据
     */
    private void handleDeviceStatusMessage(String deviceId, String data) {
        try {
            status(deviceId);
            // notifyDeviceAbnormality(deviceId, workStatus, data);
            // DeviceStatus.ABNORMAL || currentStatus == DeviceStatus.OFFLINE
        } catch (Exception e) {
            // 解析失败，忽略
        }
    }

    /**
     * 通知设备异常状态
     *
     * @param deviceId   设备ID
     * @param workStatus 工作状态
     * @param data       完整数据
     */
    private void notifyDeviceAbnormality(String deviceId, String workStatus, String data) {
        // 获取设备当前状态
        DeviceStatus currentStatus = MqttUtil.getDeviceStatus(deviceId);

        // 只有当设备不是异常状态时才通知
        if (currentStatus != DeviceStatus.ABNORMAL) {
            // 更新设备状态为异常
            MqttUtil.setDeviceStatus(deviceId, DeviceStatus.ABNORMAL);
            // 通过WebSocket发送设备异常状态通知
            DeviceWebSocket.broadcastDeviceAbnormality(deviceId, workStatus, data);
        }
    }

    private void notifyDeviceTelemetry(String deviceId, String data) {
        // 通过WebSocket发送设备异常状态通知
        JSONObject json = JSON.parseObject(data);
        DeviceWebSocket.broadcastDeviceTelemetry(deviceId, json.getString("BAT_V"));
    }

    @Override
    public void onDeviceAbnormality(String deviceId, String abnormality) {
        // 解析异常状态消息
        String workStatus = "UNKNOWN";
        // 更新设备状态为异常
        MqttUtil.setDeviceStatus(deviceId, DeviceStatus.ABNORMAL);
        // 通过WebSocket发送设备异常状态通知
        DeviceWebSocket.broadcastDeviceAbnormality(deviceId, workStatus, abnormality);
    }

    @Override
    public void onDeviceText(String deviceId, String text) {
        // 通过WebSocket发送设备文本数据
        DeviceWebSocket.broadcastDeviceText(deviceId, text);
    }

    @Override
    public void onDeviceBinary(String deviceId, byte[] data) {

    }

    /**
     * 根据数据内容确定设备类型
     *
     * @param data 设备发送的数据
     * @return 设备类型
     */
    private String determineDeviceType(String data) {
        // 默认返回未知类型
        return DeviceTypeManager.DEVICE_TYPE_IS0360A;
    }
}